/*
 * Copyright (c) 2015, Freescale Semiconductor, Inc.
 * Copyright 2016-2019 NXP
 * All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include "pin_mux.h"
#include "clock_config.h"
#include "board.h"
#include "fsl_lpuart.h"
#include "fsl_debug_console.h"

#include "fsl_clock.h"

#include "TimeSeries.h"
/************************************************************** *****************
 * Definitions
 ******************************************************************************/
#define DEMO_LPUART            LPUART5
#define DEMO_LPUART_CLK_FREQ   CLOCK_GetLPFlexCommClkFreq(4u)
#define DEMO_LPUART_IRQn       LP_FLEXCOMM5_IRQn
#define DEMO_LPUART_IRQHandler LP_FLEXCOMM5_IRQHandler


/*******************************************************************************
 * Prototypes
 ******************************************************************************/

/*******************************************************************************
 * Variables
 ******************************************************************************/


uint8_t g_tipString[] =
    "eIQ Motor check demo\r\nNow please press the board Reset button and Reset the Motor!\r\n";

/*******************************************************************************
 * Tss
 ****************************************************************************/
float probability;
status_t status;
float data_Input[TSS_INPUT_DATA_LEN * TSS_INPUT_DATA_DIM];


/*******************************************************************************
 * LPUART5
 ****************************************************************************/

#if true
#define MAX_DATA_SIZE 500
#define RX_BUF_SIZE   16                /* 根据最大数字长度+2(\r\n)设置 */

volatile char rx_buf[RX_BUF_SIZE];      /* 接收缓冲区    */

volatile uint16_t data_index = 0;       /* 数据存储索引  */
volatile uint8_t rx_cnt      = 0;       /* 接收缓冲计数  */
volatile bool cmd_ready      = false;   /* 命令就绪标志  */

void DEMO_LPUART_IRQHandler(void)
{
    /* 检查接收中断标志 */
    if ((LPUART_GetStatusFlags(DEMO_LPUART) & kLPUART_RxDataRegFullFlag))
    {
        uint8_t ch = LPUART_ReadByte(DEMO_LPUART);

#if 1

        /* 处理结束符 */
        if (ch == '\r' || ch == '\n')
        {
            /* 有效数据 */
            if (rx_cnt > 0)
            {
                /* 添加字符串终结符 */
                rx_buf[rx_cnt] = '\0';
                //PRINTF("11\r\n");
                cmd_ready = true;
            }
            rx_cnt = 0;
        }
        else
        {
            /* 防止溢出 */
            if (rx_cnt < RX_BUF_SIZE - 1)
            {
                rx_buf[rx_cnt++] = ch;
            }
            else            /* 缓冲区溢出处理 */
            {
                rx_cnt = 0; /* 丢弃错误数据   */
            }
        }
#endif /* 0 */
        //LPUART_ClearStatusFlags(DEMO_LPUART,kLPUART_IdleLineFlag);
        SDK_ISR_EXIT_BARRIER;
    }
}
#endif /* true */
/*******************************************************************************
 * LPUART4
 ****************************************************************************/
void lpuart4_init(uint32_t BAUD)
{
    CLOCK_EnableClock(kCLOCK_Gpio0);
    CLOCK_SetClkDiv(kCLOCK_DivFlexcom4Clk, 1u);  //  kCLOCK_DivFlexcom5Clk  kCLOCK_DivFlexcom4Clk
    CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH); // kFRO12M_to_FLEXCOMM5   BOARD_DEBUG_UART_CLK_ATTACH

    lpuart_config_t config;
    LPUART_GetDefaultConfig(&config);
    config.baudRate_Bps = BAUD;
    config.enableTx     = true;
    config.enableRx     = true;
    LPUART_Init(LPUART4, &config, CLOCK_GetLPFlexCommClkFreq(5U));
    /* Send g_tipString out. */
    /* Enable RX interrupt. */
    LPUART_EnableInterrupts(LPUART4, kLPUART_RxDataRegFullInterruptEnable);
    EnableIRQ(LP_FLEXCOMM4_IRQn);

}

void LP_FLEXCOMM4_IRQHandler(void)
{
    uint8_t Temp;
#define rx_Size 5
    uint8_t rx_Buffer[rx_Size];
    uint16_t rx_Index = 0;
    if ((kLPUART_RxDataRegFullFlag)&LPUART_GetStatusFlags(LPUART4))   /* 发生中断 */
    {

        Temp = LPUART_ReadByte(LPUART4);
        LPUART_WriteByte(LPUART4, Temp);
        SDK_ISR_EXIT_BARRIER;
    }

}

/*!
 * @brief Main function
 */
int main(void)
{
    CLOCK_EnableClock(kCLOCK_Gpio0);
    lpuart_config_t config;
    /* attach FRO 12M to FLEXCOMM4 (debug console) */
    CLOCK_SetClkDiv(kCLOCK_DivFlexcom5Clk, 1u);
    CLOCK_AttachClk(kFRO12M_to_FLEXCOMM5);
    BOARD_InitPins();

    BOARD_InitBootClocks();
    BOARD_InitDebugConsole();
    /*
     * config.baudRate_Bps = 115200U;
     * config.parityMode = kLPUART_ParityDisabled;
     * config.stopBitCount = kLPUART_OneStopBit;
     * config.txFifoWatermark = 0;
     * config.rxFifoWatermark = 0;
     * config.enableTx = false;
     * config.enableRx = false;
     */
    LPUART_GetDefaultConfig(&config);
    config.baudRate_Bps = BOARD_DEBUG_UART_BAUDRATE;
    config.enableTx     = true;
    config.enableRx     = true;
    LPUART_Init(DEMO_LPUART, &config, DEMO_LPUART_CLK_FREQ);
    /* Send g_tipString out. */
//    LPUART_WriteBlocking(LPUART4, g_tipString, sizeof(g_tipString) / sizeof(g_tipString[0]));
    //PRINTF("eIQ Motor check demo\r\nNow please press the board Reset button and Reset the Motor!\r\n");
    /* Enable RX interrupt. */
    LPUART_EnableInterrupts(DEMO_LPUART, kLPUART_RxDataRegFullInterruptEnable);
    EnableIRQ(DEMO_LPUART_IRQn);
    lpuart4_init(115200);

    INIT_LED_PINS(RED, LOGIC_LED_OFF);
    INIT_LED_PINS(GREEN, LOGIC_LED_OFF);
    INIT_LED_PINS(BLUE,  LOGIC_LED_OFF);

    /* models init */

    status = tss_ad_init();
    if (status != TSS_SUCCESS)
    {
        PRINTF("tss_ad_init failed!\r\n");
    }
    else
    {
        PRINTF("tss_ad_init successful!\r\n");
    }

    while (1)
    {
# if 1
        if (cmd_ready)
        {
            cmd_ready = false;

            /* 转换为整数 */
            uint32_t num = atoi((char *)rx_buf);    // DATA[] = {'1', '7','5','0','\0'}

            /* 有效性检查 */

            if (data_index < MAX_DATA_SIZE)
            {
                data_Input[ data_index++ ] = (float)num;

                /* 数组存满处理 */
                if (data_index >= MAX_DATA_SIZE)
                {
                    /* 执行预测 */
                    status = tss_ad_predict(data_Input, &probability);
                    if (probability >= 0.9)
                    {

                        LED_RED_INIT(1);
                        LED_GREEN_INIT(0);
                        PRINTF("Motor Normal!\r\n");
                        PRINTF("probability value is:%f\r\n", probability);

                    }
                    else
                    {
                        LED_RED_INIT(0);
                        LED_GREEN_INIT(1);
                        PRINTF("Motor Anomaly!\r\n");
                        PRINTF("probability value is:%f\r\n", probability);

                    }

                    PRINTF("data size is:%d\r\n", sizeof(data_Input) / sizeof(data_Input[0]));
                    PRINTF("OK\r\n");
                    data_index = 0; // 重置索引
                    memset(data_Input, 0, sizeof(data_Input)/sizeof(data_Input[0]));
                }
            }

        }
#endif /* 0 */
    }

}
